package com.chuangke.message.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chuangke.admin.entity.SysUser;
import com.chuangke.admin.service.SysUserService;
import com.chuangke.common.db.page.CkPageQuery;
import com.chuangke.common.exception.ChuangkeException;
import com.chuangke.common.idgen.IdManager;
import com.chuangke.common.utils.SecurityUtils;
import com.chuangke.message.constant.MsgConstants;
import com.chuangke.message.dao.SysMessageDao;
import com.chuangke.message.dto.SendMessageDto;
import com.chuangke.message.entity.SysMessage;
import com.chuangke.message.service.SysMessageService;

@Service
public class SysMessageServiceImpl implements SysMessageService {

	@Autowired
	private SysMessageDao sysMessageDao;

	@Autowired
	private SysUserService sysUserService;

	@Override
	public void send(SendMessageDto msgDto) {
		List<SysUser> userList = null;
		List<String> userIdList = null;
		switch (msgDto.getToType()) {
		case SendMessageDto.TO_TYPE_ALL:
			userList = sysUserService.findList();
			userIdList = userList.stream().map(SysUser::getId).collect(Collectors.toList());
			break;
		case SendMessageDto.TO_TYPE_DEPT:
			userList = sysUserService.findList();
			userList = userList.stream().filter(u -> msgDto.getToIds().contains(u.getDeptId())).collect(Collectors.toList());
			userIdList = userList.stream().map(SysUser::getId).collect(Collectors.toList());
			break;
		case SendMessageDto.TO_TYPE_USER:
			userIdList = msgDto.getToIds();
			break;
		default:
			throw new ChuangkeException("参数传输不对");
		}

		List<SysMessage> msgList = new ArrayList<>(userIdList.size());
		userIdList.forEach(user -> {
			SysMessage sysMessage = new SysMessage();
			sysMessage.setId(IdManager.nextId());
			sysMessage.setTitle(msgDto.getTitle());
			sysMessage.setContent(msgDto.getMessage());
			sysMessage.setId(IdManager.nextId());
			sysMessage.setReceiver(user);
			sysMessage.setSender(msgDto.getFromUser());
			sysMessage.setSendTime(new Date());
			sysMessage.setStatus(MsgConstants.STATUS_UNREAD);
			sysMessage.setType(MsgConstants.TYPE_SYSTEM);

			msgList.add(sysMessage);
		});

		send(msgList);
	}

	@Async
	@Override
	public void systemSend(String toUser, String message) {
		send(MsgConstants.SYSTEM_USER, toUser, MsgConstants.TYPE_SYSTEM, message);
	}

	@Override
	public void send(String fromUser, String toUser, String type, String message) {
		send(fromUser, toUser, type, message, message);
	}

	@Override
	public void send(String fromUser, String toUser, String type, String title, String message) {
		SysMessage sysMessage = new SysMessage();
		sysMessage.setId(IdManager.nextId());
		sysMessage.setTitle(message);
		sysMessage.setContent(message);
		sysMessage.setId(IdManager.nextId());
		sysMessage.setReceiver(toUser);
		sysMessage.setSender(fromUser);
		sysMessage.setSendTime(new Date());
		sysMessage.setStatus(MsgConstants.STATUS_UNREAD);
		sysMessage.setType(MsgConstants.TYPE_SYSTEM);

		send(Arrays.asList(sysMessage));
	}

	@Override
	public void send(List<SysMessage> sysMessages) {
		sysMessageDao.saveBatch(sysMessages);
	}

	@Override
	public long findUnReadCount(String user, String status) {
		QueryWrapper<SysMessage> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().eq(SysMessage::getReceiver, user);
		if (status != null && !status.trim().isEmpty()) {
			queryWrapper.lambda().eq(SysMessage::getStatus, status);
		}
		queryWrapper.lambda().orderByDesc(SysMessage::getSendTime);
		return sysMessageDao.count(queryWrapper);
	}

	@Override
	public void markRead(List<String> ids) {
		if (ids == null || ids.isEmpty()) {
			return;
		}

		UpdateWrapper<SysMessage> updateWrapper = new UpdateWrapper<>();
		updateWrapper.lambda().set(SysMessage::getStatus, MsgConstants.STATUS_READED);
		updateWrapper.lambda().in(SysMessage::getId, ids);
		sysMessageDao.update(updateWrapper);
	}

	@Override
	public void markDone(List<String> ids) {
		if (ids == null || ids.isEmpty()) {
			return;
		}

		UpdateWrapper<SysMessage> updateWrapper = new UpdateWrapper<>();
		updateWrapper.lambda().set(SysMessage::getStatus, MsgConstants.STATUS_DONE);
		updateWrapper.lambda().in(SysMessage::getId, ids);
		sysMessageDao.update(updateWrapper);
	}

	@Override
	public SysMessage load(String id) {
		markRead(Collections.singletonList(id));
		return sysMessageDao.getById(id);
	}

	@Override
	public IPage<SysMessage> find(CkPageQuery page) {
		// listType:查询类型（s:发送方；r:接收方）
		String listType = (String) page.getOrDefault("listType", "r");
		String userid = SecurityUtils.getUserId();

		QueryWrapper<SysMessage> queryWrapper = new QueryWrapper<>();

		if ("s".equals(listType)) {
			queryWrapper.lambda().eq(SysMessage::getSender, userid);
		} else {
			queryWrapper.lambda().eq(SysMessage::getReceiver, userid);
		}

		String status = (String) page.get("status");
		if (status != null && !status.isEmpty()) {
			queryWrapper.lambda().eq(SysMessage::getStatus, status);
		}
		queryWrapper.lambda().orderByDesc(SysMessage::getSendTime);
		return sysMessageDao.page(page.getPage(), queryWrapper);
	}

}
